const DrawArea = require('./drawingArea.js');
const AxisX = require('./axisX.js');
const AxisY = require('./axisY.js');
const Point = require('./point.js');
let that = null;

const init = Symbol('init'); // 初始化
const buildDrawArea = Symbol('buildDrawArea'); // 构建图表区绘制数据
const buildAxisX = Symbol('buildAxisX'); // 构建横坐标绘制数据
const buildAxisY = Symbol('buildAxisY'); // 构建纵坐标绘制数据
const buildPoints = Symbol('buildPoints'); // 构建数据点绘制数据

const drawDrawingArea = Symbol('drawDrawingArea'); // 绘制函数-绘制图表区
const drawAxisX = Symbol('drawAxisX'); // 绘制函数-绘制x轴
const drawAxisY = Symbol('drawAxisY'); // 绘制函数-绘制y轴
const drawPoint = Symbol('drawPoint'); // 绘制函数-绘制点
const darwAverage = Symbol('darwAverage'); // 绘制函数-绘制平均值
const drawTextInfo = Symbol('drawTextInfo'); // 绘制函数-文字文字

const getMaxValue = Symbol('getMaxValue'); // 获取数据最大值
const getAxisYInterval = Symbol('getAxisYInterval'); // 计算y轴数据间隔
const getAverage = Symbol('getAverage'); // 计算平均值
const getMinValue = Symbol('getMinValue'); // 获取最小值

class Chart {
	constructor (param) {
		if (that) return that;
		this.data = param.data || []; // 数据
		this.config = param.config || {}; // 配置数据
		this.ctx = param.ctx; // canvas上下文
		this.drawArea = null; // 图表区
		this.axisX = []; // x坐标绘制对象数组
		this.axisY = []; // y坐标绘制对象数组
		this.points = []; // 点对象数组
		this.ratio = 0; // 画布高度与数据比率
		this.average = 0; // 平均值
		this.max = 0; // 最高
		this.min = 0; // 最低
		that = this;
		this[init]();
		return that;
	}

	// 更新修改数据
	updateData (data) {
		this.data = data;
		this.axisX = [];
		this.axisY = [];
		this.points = [];
		this[init]();
	}

	// 初始化
	[init] () {
		/* 构建 */
		// 构建图表区绘制数据
		this[buildDrawArea]({
			x: this.config.width * .0895, y: this.config.height * .25,
			width: this.config.width * .8955, height: this.config.height * .625
		});
		// 构建横坐标绘制数据
		this[buildAxisX]();
		// 构建纵坐标绘制数据
		this[buildAxisY]();
		this.ratio = this.drawArea.height / this[getMaxValue]();
		this[getMinValue]();
		// 构建数据点绘制数据
		this[buildPoints]();
		this.average = this[getAverage]();


		/* 绘制 */
		this[drawAxisX](); // 绘制X轴
		this[drawAxisY](); // 绘制y轴
		this[drawPoint](); // 绘制点
		this[darwAverage](); // 绘制平均值
		this[drawTextInfo](); // 绘制文字信息

		this.ctx.draw();
	}

	// 构建图表区绘制数据
	[buildDrawArea] (param) {
		this.drawArea = new DrawArea({
			...param
		})
	}

	// 构建横坐标绘制数据
	[buildAxisX] () {
		let y = this.drawArea.y + this.drawArea.height + 15,
			startX = this.drawArea.x, endX = this.drawArea.x + this.drawArea.width,
			perWidth = (this.drawArea.width - 10) / this.data.length,
			fontSize = this.config.axis.x.fontSize ? this.config.axis.x.fontSize : this.config.fontSize,
			color = this.config.axis.x.color ? this.config.axis.x.color : this.config.axis.color;
		for(let i = 0; i < this.data.length; i += 1) {
			let temp = this.data[i];
			if (this.config.axis.x.isHideBetween) {
				if(i === 0 || i === this.data.length - 1) {
					this.axisX.push(new AxisX({
						fontSize, color, text: temp.text, x: i * perWidth + startX, y
					}))
				} else { 
					this.axisX.push(new AxisX({
						fontSize, color, text: '', x: i * perWidth + startX, y
					}))
				};
			} else {
				this.axisX.push(new AxisX({
					fontSize, color, text: temp.text, x: i * perWidth + startX, y
				}))
			}
		}
	}

	// 构建纵坐标绘制数据
	[buildAxisY] () {
		let max = this[getMaxValue](),
			interval = this[getAxisYInterval](max),
			preHeight = this.drawArea.height / this.config.axis.y.count,
			startY = this.drawArea.y, endY = this.drawArea.y + this.drawArea.height,
			fontSize = this.config.axis.y.fontSize ? this.config.axis.y.fontSize : this.config.fontSize,
			color = this.config.axis.y.color ? this.config.axis.y.color : this.config.axis.color,
			lineWidth = this.config.axis.y.lineWidth ? this.config.axis.y.lineWidth : this.config.axis.lineWidth,
			lineColor = this.config.axis.y.lineColor ? this.config.axis.y.lineColor : this.config.axis.lineColro;
		for(let i = 0; i < this.config.axis.y.count; i += 1) {
			this.axisY.push(new AxisY({
				value: interval * (i + 1), fontSize, color, lineWidth, lineColor, width: this.drawArea.width, x: 0,
				y: (this.config.axis.y.count - i) * preHeight + this.drawArea.y - preHeight
			}))
		}
		this.axisY.unshift(new AxisY({
			value: '', fontSize, color, lineWidth, lineColor, width: this.drawArea.width, x: 0,
			y: this.drawArea.y + this.drawArea.height
		}))
	}

	// 构建数据点绘制数据
	[buildPoints] () {
		let lineWidth = this.config.point.lineWidth,
			lineColor = this.config.point.lineColor,
			scalePoint = this.config.point.scalePoint || false,
			radius = this.config.point.radius || 0;
		for(let i = 0; i < this.axisX.length; i += 1) {
			let tempAxisX = this.axisX[i];
			let tempData = this.data[i];
			this.points.push( new Point({
				x: tempAxisX.x,
				y: this.drawArea.y + this.drawArea.height - tempData.value * this.ratio,
				value: tempData.value, lineWidth, lineColor, scalePoint, radius, index: i,
			}))
		}
	}

	// 获取最大值
	[getMaxValue] () {
		let result = 0;
		for(let i = 0; i < this.data.length; i += 1) {
			let temp = this.data[i];
			if(+temp.value > result) result = +temp.value;
		}
		this.max = result;
		return result;
	}

	// 获取最小值
	[getMinValue] () {
		let result = this.max;
		for(let i = 0; i < this.data.length; i += 1) {
			let temp = this.data[i];
			if(+temp.value < result) result = +temp.value
		}
		this.min = result;
		return result;
	}

	// 计算y轴数据间隔
	[getAxisYInterval] (max) {
		let tempMax = max;
		while (tempMax % 10 > 0) {
			tempMax += 1;
		}
		while (tempMax % this.config.axis.y.count > 0 || tempMax % 10 > 0) {
			tempMax++;
		}
		return tempMax / this.config.axis.y.count;
	}

	// 计算平均值
	[getAverage] () {
		let total = 0;
		for(let i = 0; i < this.data.length; i += 1) {
			let temp = this.data[i];
			total += temp.value;
		}
		return total / this.data.length;
	}
	
	// 绘制X轴
	[drawAxisX] () {
		for(let i = 0; i < this.axisX.length; i += 1) {
			let temp = this.axisX[i];
			temp.draw(this.ctx);
			if(i === this.axisX.length - 1) {
				AxisX.drawUnit(this.ctx, this.config.axis.x.unit, temp.x + 20, temp.y);
			}
		}
	}

	// 绘制y轴
	[drawAxisY] () {
		for(let i = 0; i < this.axisY.length; i += 1) {
			let temp = this.axisY[i];
			temp.draw(this.ctx, this.drawArea.x);
			if(i === this.axisY.length - 1) {
				AxisY.drawUnit(this.ctx, this.config.axis.y.unit, temp.x, temp.y - 30);
			}
		}
	}

	// 绘制点
	[drawPoint] () {
		this.ctx.beginPath();
		this.ctx.setLineDash([10, 0], 0);
		for(let i = 0; i < this.points.length; i += 1) {
			let tempPoint = this.points[i];
			tempPoint.draw(this.ctx);
		}
		this.ctx.stroke();
		if (this.config.point.scalePoint ) {
			for (let i = 0; i < this.points.length; i += 1) {
				let tempPoint = this.points[i];
				tempPoint.drawPoint(this.ctx);
			}
		}
	}

	// 绘制平均值
	[darwAverage] () {
		let y = this.drawArea.y + this.drawArea.height - this.average * this.ratio;
		this.ctx.setLineDash(this.config.axis.average.array, this.config.axis.average.offset);
		this.ctx.beginPath();
		this.ctx.setStrokeStyle(this.config.axis.average.color || '#d4d4d4');
		this.ctx.moveTo(this.drawArea.x, y);
		this.ctx.lineTo(this.drawArea.x +this.drawArea.width, y);
		this.ctx.stroke();
	}

	// 绘制文字信息
	[drawTextInfo] () {
		this.ctx.setFontSize(this.config.text.fontSize || 20);
		this.ctx.setFillStyle(this.config.text.color || '#aaa');
		this.ctx.setTextAlign('right');
		this.ctx.setTextBaseline('middle');
		this.ctx.fillText(`最高：${this.max}笔`, this.config.text.x, this.config.text.y);
		this.ctx.fillText(`最低：${this.min}笔`, this.config.text.x, this.config.text.y + this.config.text.marginBot);
		this.ctx.fillText(`均值：${Math.round(this.average)}笔`, this.config.text.x, this.config.text.y + this.config.text.marginBot * 2);
	}
}

module.exports = Chart;